/*
 * Copyright (c) 2022, IMMORTA Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * - Neither the name of IMMORTA Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef HSM_REG_ACCESS_H
#define HSM_REG_ACCESS_H

/*!
 * @file hsm_reg_access.h
 * @brief This file declares or defines hsm register access functions,
 *        the following mailbox functions are protocol for mailbox communication,
 *        user cannot be modified
 */

/*******Includes***************************************************************/
#include "device_registers.h"

/*******Definitions************************************************************/
#define MAILBOX_S2H_INFO_MAXNUM         (32U)
#define MAILBOX_CMD_FLAG_MASK           (0x00000001U)

/*******APIs*******************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif

/*!
 * @brief Mailbox write the command
 *
 * @param[in] cmdBuf: The command buffer
 * @param[in] cmdWordLen: command size in word
 * @return None
 */
static inline void MBOX_REG_WriteCommand(uint32_t* cmdBuf, uint32_t cmdWordLen)
{
    ASSERT_PARAM(cmdWordLen <= MAILBOX_S2H_INFO_MAXNUM);

    for (uint32_t i = 0; i < cmdWordLen; i++) {
        MBOX->S2H_INFO[i] = cmdBuf[i];
    }
}

/*!
 * @brief Mailbox start executing command
 *
 * @param[in] None
 * @return None
 */
static inline void MBOX_REG_StartCommand(void)
{
    /* set mailbox note register,The S2H_NOTE flag bit is cleared by the HSM */
    MBOX->S2H_NOTE = MAILBOX_CMD_FLAG_MASK;
}

/*!
 * @brief Get command idle status
 *
 * @param[in] None
 * @return status:
 *          - true: command idle
 *          - false: command in progress,busy
 */
static inline bool MBOX_REG_GetCommandIdleStatus(void)
{
    if ((MBOX->H2S_NOTE & MAILBOX_CMD_FLAG_MASK) ||
            (MBOX->S2H_NOTE & MAILBOX_CMD_FLAG_MASK)) {
        return false;
    } else {
        return true;
    }
}

/*!
 * @brief Get command completion status
 *
 * @param[in] None
 * @return status:
 *          - true: command is complete
 *          - false: command in progress
 */
static inline bool MBOX_REG_GetCommandCompletionStatus(void)
{
    if (MBOX->H2S_NOTE & MAILBOX_CMD_FLAG_MASK) {
        return true;
    } else {
        return false;
    }
}

/*!
 * @brief Clear command completion status
 *
 * @param[in] None
 * @return None
 */
static inline void MBOX_REG_ClearCommandCompletionStatus(void)
{
    /* clear mailbox note flag */
    MBOX->H2S_NOTE = MAILBOX_CMD_FLAG_MASK;
    /* clear mailbox note interrupt flag */
    MBOX->H2S_SOC_INT = MAILBOX_CMD_FLAG_MASK;
}

/*!
 * @brief Get command response,It is used to judge the command execution
 *
 * @param[in] None
 * @return Command response
 */
static inline uint32_t MBOX_REG_GetCommandResponse(void)
{
    return MBOX->H2S_INFO[0];
}

/*!
 * @brief Enable mailbox interrupt,while received command response
 *
 * @param[in] enable: true-enable,false-disable
 * @return None
 */
static inline void MBOX_REG_CommandIntEnable(bool enable)
{
    if (enable == true) {
        MBOX->H2S_SOC_INT_EN |= MAILBOX_CMD_FLAG_MASK;
    } else {
        MBOX->H2S_SOC_INT_EN &= ~MAILBOX_CMD_FLAG_MASK;
    }
}

/*!
 * @brief Get mailbox interrupt flag
 *
 * @param[in] None
 * @return Mailbox interrupt flag is set(true) or reset(false)
 */
static inline bool MBOX_REG_GetCommandIntFlag(void)
{
    if (MBOX->H2S_SOC_INT & MAILBOX_CMD_FLAG_MASK) {
        return true;
    } else {
        return false;
    }
}

/*!
 * @brief Get HSM FWSTA0 register value
 *
 * @param[in] None
 * @return register value
 */
static inline uint32_t HSM_REG_GetFwStatus0(void)
{
    return (uint32_t)(HSM->FWSTA0);
}

/*!
 * @brief Get HSM FWSTA1 register value
 *
 * @param[in] None
 * @return register value
 */
static inline uint32_t HSM_REG_GetFwStatus1(void)
{
    return (uint32_t)(HSM->FWSTA1);
}

/*!
 * @brief Get HSM DBGSTA register value
 *
 * @param[in] None
 * @return register value
 */
static inline uint32_t HSM_REG_GetDebugStatus(void)
{
    return (uint32_t)HSM->DBGSTA;
}

/*!
 * @brief Get Mailbox STATUS0 register value
 *
 * @param[in] None
 * @return register value
 */
static inline uint32_t HSM_REG_GetMboxStatus0(void)
{
    return (uint32_t)MBOX->STATUS0;
}

#if defined(__cplusplus)
}
#endif

#endif /* HSM_REG_ACCESS_H */

/*******EOF********************************************************************/
